import { Injectable, BadRequestException } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { CreateAnImgDto } from './dto/create-an-img.dto';
import { UpdateAnImgDto } from './dto/update-an-img.dto';
import { CreateAnFileDto } from '../an-file/dto/create-an-file.dto';
import { AnImg } from './entities/an-img.entity';
import { AnFileService } from '../an-file/an-file.service';
import { FastDFSService } from 'src/common/core/fastdfs/fastdfs.service';
import { getImageSize } from 'src/common/utils/index';
import * as sharp from 'sharp';

@Injectable()
export class AnImgService {
  constructor(
    @InjectRepository(AnImg)
    private anImgRepository: Repository<AnImg>,
    private readonly anFileService: AnFileService,
    private readonly fastDFSservice: FastDFSService,
  ) {}

  // 上传图片
  async create(files: any, createAnImgDto: CreateAnImgDto) {
    const resDate = [];
    for (const file of files) {
      const { originalname, size } = file;
      const anFileObj = new CreateAnFileDto();
      anFileObj.type = 1;
      anFileObj.description = '上传图片';
      // 调用附件上传 并存储到附件表
      const res = await this.anFileService.create(file, anFileObj);
      // 确保接受的是数字类型
      const scaleSize = parseInt(
        createAnImgDto.scaleSize as unknown as string,
        10,
      );
      // 生成缩略图
      const thumbnailBuffer = await sharp(file.buffer)
        .resize(scaleSize, scaleSize, {
          fit: 'inside',
        })
        .toBuffer();
      // 组装
      const thumbnailFile = {
        originalname: originalname,
        buffer: thumbnailBuffer,
      };
      // 上传并返回路径
      const thumbnailPath = await this.fastDFSservice.uploadFile(thumbnailFile);

      // 获取图片尺寸
      const imageSize = await getImageSize(file.buffer);
      // 创建新的CreateAnImgDto实例
      const newImg = new CreateAnImgDto();
      Object.assign(newImg, createAnImgDto, {
        fileId: res.id,
        name: originalname,
        size: size,
        url: res.path,
        scale: `${imageSize.width}x${imageSize.height}`,
        thumbnail: thumbnailPath, // 缩略图
      });
      // 存储数据到图片表
      const imgRes = await this.anImgRepository.save(newImg);
      // 返回数据
      resDate.push({
        id: imgRes.id,
        url: imgRes.url,
        thumbnail: imgRes.thumbnail,
        name: originalname,
      });
    }
    return resDate;
  }

  // 查询列表
  async findAll(query: any) {
    const {
      startTime,
      endTime,
      name,
      tag,
      type,
      orderBy,
      page = 1,
      pageSize = 10,
    } = query;

    let qb = this.anImgRepository.createQueryBuilder('anImg');
    if (startTime && endTime) {
      const parsedStartDate = new Date(startTime);
      const parsedEndDate = new Date(endTime);
      if (isNaN(parsedStartDate.getTime()) || isNaN(parsedEndDate.getTime())) {
        throw new BadRequestException('时间格式错误');
      }
      qb = qb.where(
        'anImg.createdTime BETWEEN :parsedStartDate AND :parsedEndDate',
        {
          parsedStartDate,
          parsedEndDate,
        },
      );
    }
    if (name) {
      qb = qb.where('anImg.name LIKE :name', { name: `%${name}%` });
    }
    if (type) {
      qb.andWhere('anImg.type = :type', { type: +type });
    }
    if (tag) {
      qb.andWhere('anImg.tag LIKE :tag', { tag: `%${tag}%` });
    }
    if (orderBy == 2) {
      // 添加按 createdTime 倒序排序
      qb.orderBy('anImg.createdTime', 'DESC');
    } else {
      qb.orderBy('anImg.createdTime', 'ASC');
    }
    qb = qb.skip((page - 1) * pageSize).take(pageSize);
    const [items, totalItemsCount] = await qb.getManyAndCount();
    return {
      total: totalItemsCount,
      data: items,
    };
  }

  findOne(id: string) {
    return this.anImgRepository.findOneBy({ id: id });
  }

  update(updateAnImgDto: UpdateAnImgDto) {
    const id = updateAnImgDto.id;
    return this.anImgRepository.update(id, updateAnImgDto);
  }

  // 删除图片
  async remove(ids: string[]) {
    ids.forEach(async (id) => {
      const newImg = await this.findOne(id);
      if (newImg && newImg.fileId) {
        this.anFileService.remove([newImg.fileId]);
      }
    });
    return this.anImgRepository.delete(ids);
  }
}
